﻿using NUnit.Framework;
using SpecFlowTfsLinker.Entities;
using SpecFlowTfsLinker.Printer;
using SpecFlowTfsLinker.Test.Common;
using SpecFlowTfsLinker.Test.Resources;
using SpecFlowTfsLinker.Tools;

namespace SpecFlowTfsLinker.Test.Printer
{
    [TestFixture]
    public class StatementPrinterTest : TestInitialization
    {
        private static Statement GivenBaseStatementWithParameter
        {
            get { return Statement.Given(TestCaseResources.Addition.Given.BaseStatement); }
        }

        private static Statement GivenBaseStatementWithoutParameter
        {
            get { return Statement.Given(TestCaseResources.GutterGame.Given.BaseStatement); }
        }

        [Test]
        public void CanPrintStatementWithoutParameter()
        {
            var statementPrinter = new StatementPrinter(GivenBaseStatementWithoutParameter);
            Assert.That(statementPrinter.DisplayMethodStatement, Is.EqualTo(TestCaseResources.GutterGame.Given.FinalMethodStatement));
            CollectionAssert.IsEmpty(statementPrinter.Parameters);
            Assert.That(statementPrinter.DisplayParameters, Is.Empty);
            Assert.That(statementPrinter.DisplayType, Is.EqualTo(StatementType.Given));
        }

        [Test]
        public void CanPrintStatementWithParameter()
        {
            AssertCanPrintStatement(TestCaseResources.Addition.Given);
            AssertCanPrintStatement(TestCaseResources.Addition.GivenAnd);
            AssertCanPrintStatement(TestCaseResources.Addition.GivenSecondAnd);
            AssertCanPrintStatement(TestCaseResources.Addition.When);
            AssertCanPrintStatement(TestCaseResources.Addition.WhenAnd);
            AssertCanPrintStatement(TestCaseResources.Addition.Then);
            AssertCanPrintStatement(TestCaseResources.Addition.ThenAnd);

            AssertCanPrintStatement(TestCaseResources.Word.Given);
            AssertCanPrintStatement(TestCaseResources.Word.GivenAnd);
            AssertCanPrintStatement(TestCaseResources.Word.When);
            AssertCanPrintStatement(TestCaseResources.Word.Then);
        }

        private static void AssertCanPrintStatement(TestCaseTester statementTester)
        {
            var printerToTest = new StatementPrinter(statementTester.Statement);
            Assert.That(printerToTest.DisplayMethodStatement, Is.EqualTo(statementTester.FinalMethodStatement));


            if (statementTester.NumberOfParameters > 0)
            {
                CollectionAssert.IsNotEmpty(printerToTest.Parameters);
                CollectionAssert.AllItemsAreNotNull(printerToTest.Parameters);
            }
            else
            {
                CollectionAssert.IsEmpty(printerToTest.Parameters);
            }
            Assert.That(printerToTest.Parameters.Count, Is.EqualTo(statementTester.NumberOfParameters));
            Assert.That(printerToTest.DisplayParameters, Is.EqualTo(statementTester.Parameters));
            Assert.That(printerToTest.DisplayType, Is.EqualTo(statementTester.Type));
            Assert.That(printerToTest.DisplayStatement, Is.EqualTo(statementTester.FinalStatement));
        }

        [Test]
        public void CanTransformStatementWithRegexParameter()
        {
            var givenStatementPrinterWithParameter = new StatementPrinter(GivenBaseStatementWithParameter);
            Assert.AreEqual(TestCaseResources.Addition.Given.FinalMethodStatement,
                            StatementTools.TransformStatementToStatementWithParameter(GivenBaseStatementWithParameter,
                                                                                      givenStatementPrinterWithParameter.Parameters));
        }
    }
}